﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using com.paypal.sdk.profiles;
using com.paypal.sdk.services;
using com.paypal.soap.api;
using NETMovie.Entities;

namespace NETMovie.Gateways.PayPal
{
    public class PaymentGateway
    {
        private CreditCardTypeType ConvertCCType(int ccType)
        {
            switch (ccType)
            {
                case 0:
                    return CreditCardTypeType.Visa;
                case 1:
                    return CreditCardTypeType.MasterCard;
                case 2:
                    return CreditCardTypeType.Discover;
                case 3:
                    return CreditCardTypeType.Amex;
                case 4:
                    return CreditCardTypeType.Switch;
                case 5:
                    return CreditCardTypeType.Solo;
                default:
                    throw new UserErrorException("Unsupported Credit Card Type");
            }
        }

        private CountryCodeType ConvertCountryType(string countryCode)
        {
            switch (countryCode)
            {
                case "US":
                    return CountryCodeType.US;
                case "SG":
                    return CountryCodeType.SG;
                case "UK":
                    return CountryCodeType.GB;
                case "IN":
                    return CountryCodeType.IN;
                case "VTE":
                    return CountryCodeType.VI;
                default:
                    throw new UserErrorException("Unsupported Country");
            }
        }

        public List< KeyValuePair<int, string> > GetCreditCards()
        {
            var cards = new List< KeyValuePair<int, string> >();
            cards.Add(new KeyValuePair<int, string>(0, "VISA"));
            cards.Add(new KeyValuePair<int, string>(1, "Mastercard"));
            cards.Add(new KeyValuePair<int, string>(2, "Discover"));
            cards.Add(new KeyValuePair<int, string>(3, "Amex"));
            cards.Add(new KeyValuePair<int, string>(4, "Switch"));
            cards.Add(new KeyValuePair<int, string>(5, "Solo"));

            return cards;
        }

        public string MakePayment(Payment payment)
        {
            CallerServices caller = new CallerServices();
            IAPIProfile profile = ProfileFactory.createSignatureAPIProfile();

            profile.APIUsername = ConfigurationManager.AppSettings["PayPalAPIUsername"];
            profile.APIPassword = ConfigurationManager.AppSettings["PayPalAPIPassword"];
            profile.Environment = ConfigurationManager.AppSettings["PayPalEnvironment"];
            profile.Subject = String.Empty;
            profile.APISignature = ConfigurationManager.AppSettings["PayPalAPISignature"];

            caller.APIProfile = profile;

            DoDirectPaymentRequestDetailsType directPaymentDetails = new DoDirectPaymentRequestDetailsType();

            //Set Credit Card
            CreditCardDetailsType cc = new CreditCardDetailsType();
            cc.CreditCardType = ConvertCCType(payment.CreditCardType);
            cc.CreditCardNumber = payment.CreditCardNo;
            cc.ExpMonth = payment.CCExpiryMonth;
            cc.ExpYear = payment.CCExpiryYear;
            cc.ExpMonthSpecified = true;
            cc.ExpYearSpecified = true;

            //Set Credit Card.CardOwner
            PayerInfoType theCardOwner = new PayerInfoType();
            
            PersonNameType thePayerName = new PersonNameType();
            thePayerName.FirstName = payment.PayerFirstName;
            thePayerName.LastName = payment.PayerLastName;
            theCardOwner.PayerName = thePayerName;

            AddressType theAddress = new AddressType()
            {
                Street1 = payment.AddressLine1,
                Street2 = payment.AddressLine2,
                CityName = payment.City,
                Country = (profile.Environment.Equals("sandbox")) ? CountryCodeType.US : ConvertCountryType(payment.Country.CountryCode),
                PostalCode = (profile.Environment.Equals("sandbox")) ? "32550" : payment.PostalCode,
                StateOrProvince = String.Empty,
                CountrySpecified = true
            };

            theCardOwner.Address = theAddress;

            cc.CardOwner = theCardOwner;
            directPaymentDetails.CreditCard = cc;

            //Set Order Total
            BasicAmountType temp = new BasicAmountType();

            PaymentDetailsType payDetailType = new PaymentDetailsType();
            temp.Value = payment.TransactionInfo.TotalAmount.ToString();

            if (profile.Environment.Equals("sandbox"))
                temp.currencyID = CurrencyCodeType.USD;
            else
                temp.currencyID = CurrencyCodeType.SGD;

            payDetailType.OrderTotal = temp;

            directPaymentDetails.PaymentDetails = payDetailType;

            //Set IP
            directPaymentDetails.IPAddress = "192.168.200.195";

            //Set Transaction Type
            directPaymentDetails.PaymentAction = PaymentActionCodeType.Sale;

            //Set Request
            DoDirectPaymentRequestType request = new DoDirectPaymentRequestType();
            request.DoDirectPaymentRequestDetails = directPaymentDetails;

            try
            {
                DoDirectPaymentResponseType response = (DoDirectPaymentResponseType)caller.Call("DoDirectPayment", request);

                if (response.Ack == AckCodeType.Success)
                    return response.TransactionID;
                else
                    return String.Empty;
            }
            catch (Exception ex)
            {
                throw new UserErrorException("PayPal Web Service call gave a severe error: " + ex.Message);
            }
        }
    }
}
